package com.qiangzi.workflow.engine.bpmn.base;

import org.dom4j.Attribute;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert;

public abstract class BaseElement {

    public static final Logger LOGGER    = LoggerFactory.getLogger(BaseElement.class);

    /**
     * 基本字段
     */
    private String             id;
    private String             name;

    /**
     * 是否真的被使用到了,没有使用的视为无效配置,会报异常
     */
    private boolean            connected = false;

    /**
     * 执行状态
     */
    private int                state;

    // -----------------------------------下面是GETTER/SETTER函数

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getState() {
        return state;
    }

    protected void setState(int state) {
        this.state = state;
    }

    public boolean isConnected() {
        return connected;
    }

    public void setConnected(boolean connected) {
        this.connected = connected;
    }

    public void parse(Element element) throws Exception {

        Assert.isTrue(null != element, "element is null");

        // 提取ID
        Attribute idAttribute = element.attribute("id");
        Assert.isTrue(null != idAttribute, "id must exist");
        String id = idAttribute.getText();
        Assert.hasText(id, "id is empty");
        this.id = id;

        // name属性可选
        String name = null;
        Attribute nameAttribute = element.attribute("name");
        if (null != nameAttribute) {
            name = nameAttribute.getText();
        }
        this.name = name;

    }

    public abstract Object copy();

    protected void copy(Object obj) {
        BaseElement element = (BaseElement) obj;
        element.id = this.id;
        element.name = this.name;
        element.connected = false;
        element.state = State.NEW;
    }

    public abstract void invoke(ProcessInstance instance,
                                ApplicationContext applicationContext) throws Exception;

    public abstract void ignore(ProcessInstance instance) throws Exception;

    @Override
    public String toString() {
        return this.id;
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    @Override
    public boolean equals(Object obj) {

        // 是否为空
        if (null == obj) {
            return false;
        }
        // 是否为同类型
        boolean sameType = (obj instanceof BaseElement);
        if (!sameType) {
            return false;
        }
        // 是否为同一个对象
        if (this == obj) {
            return true;
        }
        // 比较关键字段值
        return id.equals(((BaseElement) obj).getId());

    }

}
